package com.lwj.diao;

import com.lwj.diao.Utils.UtilClassLoaderExpand;
import com.lwj.diao.Utils.UtilClass;
import com.lwj.diao.Utils.UtilJar;
import com.lwj.diao.Utils.UtilOut;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class WebThread extends Thread {
    public ByteArrayOutputStream bos = new ByteArrayOutputStream();
    PrintStream exePrintStream = new PrintStream(this.bos, true);
    public InputStream iis = null;
    byte[] inputStr = null;
    public boolean isEnd = false;
    public boolean isExce = false;
    Method main = null;
    private String source = null;

    public WebThread(String source) {
        this.source = source;
    }

    public void init() {
        PrintWriter writer;
        String className = UtilClass.parseClassName(this.source);
        if (UtilClass.compile(className, this.source, writer = new PrintWriter(this.bos, true))) {
            System.setOut(this.exePrintStream);
            System.setErr(this.exePrintStream);
            try {
                UtilClassLoaderExpand clod = new UtilClassLoaderExpand();
                clod.setLocation(UtilJar.getJarDir() + "dcls/");
                Class<?> remoteClass = clod.findClass(className);
                this.main = remoteClass.getDeclaredMethod("main", String[].class);
            }
            catch (ClassNotFoundException | IllegalArgumentException | NoSuchMethodException | SecurityException e) {
                this.isExce = true;
                e.printStackTrace();
            }
        } else {
            this.isExce = true;
        }
    }

    @Override
    public void run() {
        try {
            this.parseExecuteResult();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void parseExecuteResult() throws InterruptedException {
        try {
            this.main.invoke(null, new Object[]{null});
            this.exePrintStream.close();
        }
        catch (IllegalAccessException e) {
            this.isExce = true;
            e.printStackTrace();
        }
        catch (InvocationTargetException e) {
            this.isExce = true;
            e.printStackTrace();
        }
        finally {
            System.setOut(UtilOut.OUT);
            System.setErr(UtilOut.ERR);
        }
        this.isEnd = true;
        while (this.isEnd) {
            WebThread.sleep(100000L);
        }
    }

    public void inputInit() {
        this.iis = new InputStream(){
            private int index = 0;

            @Override
            public int read() throws IOException {
                while (WebThread.this.inputStr == null) {
                    try {
                        Thread.sleep(10L);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                int clone = this.index++;
                if (this.index > WebThread.this.inputStr.length) {
                    WebThread.this.inputStr = null;
                    this.index = 0;
                    return -1;
                }
                return WebThread.this.inputStr[clone];
            }
        };
    }
}